﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Abp.Authorization.Users;
using Abp.Domain.Entities.Auditing;

namespace Abp.Authorization.Roles
{
    /// <summary>
    /// Represents a role in an application. A role is used to group permissions.
    /// 代表应用程序中的一个角色。角色被用来组织权限。
    /// </summary>
    /// <remarks> 
    /// Application should use permissions to check if user is granted to perform an operation.
    /// Checking 'if a user has a role' is not possible until the role is static (<see cref="AbpRoleBase.IsStatic"/>).
    /// Static roles can be used in the code and can not be deleted by users.
    /// Non-static (dynamic) roles can be added/removed by users and we can not know their name while coding.
    /// A user can have multiple roles. Thus, user will have all permissions of all assigned roles.
    /// 应用程序应该使用权限来检查用户是否被授权执行一个操作。
    /// 检查 ‘一个用户是否拥有一个角色’ 是不可能，除非这个角色是静态的（<see cref="AbpRoleBase.IsStatic"/>）。
    /// 静态角色可以在代码中使用，但不能被用户删除。
    /// 非静态（动态）角色可以被用户添加/移除，并且在我们编写代码时不知道它们的名称。
    /// 珍上用户可以拥有多个角色。因此，用户将拥有所有已分派角色的所有权限。
    /// </remarks>
    public abstract class AbpRole<TUser> : AbpRoleBase, IFullAudited<TUser>
        where TUser : AbpUser<TUser>
    {
        /// <summary>
        /// Unique name of this role.
        /// 该角色的唯一名称。
        /// </summary>
        [Required]
        [StringLength(MaxNameLength)]
        public virtual string NormalizedName { get; set; }

        /// <summary>
        /// Claims of this user.
        /// 该用户的声明集合。
        /// </summary>
        [ForeignKey("RoleId")]
        public virtual ICollection<RoleClaim> Claims { get; set; }

        /// <summary>
        /// A random value that must change whenever a user is persisted to the store
        /// 一个随机值，当用户被持久化到存储时必须更改。
        /// </summary>
        public virtual string ConcurrencyStamp { get; set; } = Guid.NewGuid().ToString();

        public virtual TUser DeleterUser { get; set; }

        public virtual TUser CreatorUser { get; set; }

        public virtual TUser LastModifierUser { get; set; }

        protected AbpRole()
        {
            SetNormalizedName();
        }

        /// <summary>
        /// Creates a new <see cref="AbpRole{TUser}"/> object.
        /// 创建一个新的 <see cref="AbpRole{TUser}"/> 对象。
        /// </summary>
        /// <param name="tenantId">TenantId or null (if this is not a tenant-level role) - 租户 Id 或空引用（<c>null</c>，当不是租户级别的角色）</param>
        /// <param name="displayName">Display name of the role - 角色的显示名称。</param>
        protected AbpRole(int? tenantId, string displayName)
            : base(tenantId, displayName)
        {
            SetNormalizedName();
        }

        /// <summary>
        /// Creates a new <see cref="AbpRole{TUser}"/> object.
        /// 创建一个新的 <see cref="AbpRole{TUser}"/> 对象。
        /// </summary>
        /// <param name="tenantId">TenantId or null (if this is not a tenant-level role) - 租户 Id 或空引用（<c>null</c>，当不是租户级别的角色）</param>
        /// <param name="name">Unique role name - 唯一的角色名称。</param>
        /// <param name="displayName">Display name of the role - 角色的显示名称。</param>
        protected AbpRole(int? tenantId, string name, string displayName)
            : base(tenantId, name, displayName)
        {
            SetNormalizedName();
        }

        public void SetNormalizedName()
        {
            NormalizedName = Name.ToUpperInvariant();
        }
    }
}